package nio.demo;

import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * @Desc:   scatter / gather 的案例
 * @author: cww
 * @DateTime: 2020-02-02 23:34
 */

public class ScatterGatherDemo {
    public static void main(String[] args) throws Exception{
        RandomAccessFile file = new RandomAccessFile("src\\maindemo\\resources\\file\\nio\\nio-data.txt", "rw");
        FileChannel inChannel = file.getChannel();
        ByteBuffer header = ByteBuffer.allocate(128);
        ByteBuffer body = ByteBuffer.allocate(1024);

        ByteBuffer[] bufferArray = {header, body};
        // read()方法按照buffer在数组中的顺序将从channel中读取的数据写入到buffer，
        // 当一个buffer被写满后，channel紧接着向另一个buffer中写
        // Scattering Reads在移动下一个buffer前，必须填满当前的buffer，
        // 这也意味着它不适用于动态消息。换句话说，如果存在消息头和消息体，
        // 消息头必须完成填充（例如 128byte），Scattering Reads才能正常工作
        // 优化，是否可以在消息中判断消息头大小后再进行 header 空间的分配，这样就可以
        // 动态读取了
        inChannel.read(bufferArray);

        /*------------------------------*/
        // 注意只有position和limit之间的数据才会被写入
        // 因此，如果一个buffer的容量为128byte，但是仅仅包含58byte的数据，
        // 那么这58byte的数据将被写入到channel中。因此与Scattering Reads相反，
        // Gathering Writes能较好的处理动态消息
        inChannel.write(bufferArray);
    }
}
